package net;

import data.user.User;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Andrea
 */
public class Connection {

    private User user;
    private final Socket socket;
    private ProtocolManager manager;

    private PacketBuffer pb;

    public Connection(Socket socket) throws IOException {
        this.socket = socket;

        init();
    }

    public Connection(String address, int port) throws IOException {
        this.socket = new Socket(address, port);

        init();
    }

    public Connection(InetAddress address, int port) throws IOException {
        this.socket = new Socket(address, port);

        init();
    }

    private void init() throws IOException {

        if (!Files.exists(new File("user.sav").toPath())) {
            user = new User();
        } else {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.sav"))) {
                user = (User) ois.readObject();
            } catch (IOException | ClassNotFoundException ex) {
                Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        pb = new PacketBuffer(socket.getInputStream());

        manager = new ProtocolManager();
    }

    public void start() {
        manager.start();
    }

    protected synchronized void sendPacket(Packet p) throws IOException {
        socket.getOutputStream().write(p.toByteArr());
    }

    protected synchronized void sendPacket(short encryptionType, Packet.DataType ty, byte[] data) throws IOException {
        byte b[] = new Packet(encryptionType, ty, data).toByteArr();

        socket.getOutputStream().write(
                b
        );
    }

    protected synchronized void sendPacket(Packet.DataType ty, byte[] data) throws IOException {
        byte b[] = new Packet((short) 0, ty, data).toByteArr();
        
        socket.getOutputStream().write(
                b
        );
    }

    private class ProtocolManager extends Thread {

        @Override
        public void run() {

            while (true) {
                Packet p;
                try {

                    System.out.println("in listening");
                    p = pb.getNext();
                } catch (IOException ex) {
                    Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, "End when trying to read the response from the server", ex);
                    break;
                }

                switch (p.getDataCode()) {
                    case ID:
                        System.out.println("getting id");
                        
                        user.setId(Utility.bytesToLong(p.getData()));
                        break;
                    case PASSWORD:
                        System.out.println("password requested");
                        
                        user.setPassword(Utility.generatePassword());

                        try {
                            sendPacket((short) 1, Packet.DataType.PASSWORD, user.getPassword().getBytes());
                        } catch (IOException ex) {
                            Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        break;
                    case LOGIN:
                        if (user.getId() != null && user.getPassword() != null) {

                            try {
                                System.out.println("login request");

                                sendPacket((short) 1, Packet.DataType.LOGIN, (user.getId() + " " + user.getPassword()).getBytes());
                            } catch (IOException ex) {
                                Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        } else if (user.getId() == null) {
                            try {
                                System.out.println("login request without credentials");

                                sendPacket(Packet.DataType.ID, null);
                            } catch (IOException ex) {
                                Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                        break;
                    case SPECIFICS:
                        
                        break;
                    case JOB:

                        break;
                    case JOB_LIB:

                        break;
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {

        Connection c = new Connection("localhost", 7777);

        c.start();
    }
}
